#include "ArgsBinding.h"

#include "Delegate/EventHandler.h"

using namespace xgu;

#include <iostream>

using namespace std;

class ArgsBinding
{
public:
	void foo() { cout << "void foo()" << endl; }
	void foo(int arg0) { cout << "void foo(int arg0)" << endl; }
	void foo(int arg0, int arg1) { cout << "void foo(int arg0, int arg1)" << endl; }
	void foo(int arg0, int arg1, int arg2) { cout << "void foo(int arg0, int arg1, int arg2)" << endl; }
	void foo(int arg0, int arg1, int arg2, int arg3, int arg4,
		int arg5, int arg6, int arg7, int arg8, int arg9) 
	{ 
		cout << "void foo(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9)" << endl; 
	}

	int bar() { cout << "void bar()" << endl; return 0; }
	int bar(int arg0) { cout << "void bar(int arg0)" << endl; return 0; }
	int bar(int arg0, int arg1) { cout << "void bar(int arg0, int arg1)" << endl; return 0; }
	int bar(int arg0, int arg1, int arg2) { cout << "void bar(int arg0, int arg1, int arg2)" << endl; return 0; }
	int bar(int arg0, int arg1, int arg2, int arg3, int arg4,
		int arg5, int arg6, int arg7, int arg8, int arg9) 
	{ 
		cout << "void bar(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9)" << endl; 
		return 0;
	}
};

void TestArgsBinding()
{
	ArgsBinding dt;

	Delegate<void> foo0(dt, &ArgsBinding::foo);
	Delegate<void, int> foo1(dt, &ArgsBinding::foo);
	Delegate<void, int, int> foo2(dt, &ArgsBinding::foo);
	Delegate<void, int, int, int, int, int,
		int, int, int, int, int> foo10(dt, &ArgsBinding::foo);

	foo0();
	foo1(1);
	foo2(1, 2);
	foo10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

	Delegate<int> bar0(dt, &ArgsBinding::bar);
	Delegate<int, int> bar1(dt, &ArgsBinding::bar);
	Delegate<int, int, int> bar2(dt, &ArgsBinding::bar);
	Delegate<int, int, int, int, int, int,
		int, int, int, int, int> bar10(dt, &ArgsBinding::bar);

	bar0();
	bar1(1);
	bar2(1, 2);
	bar10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

	// Argument Binding Test
	foo0.Add(dt, &ArgsBinding::foo, 1);
	foo0();
	foo0.Remove(dt, &ArgsBinding::foo, 1);
	foo0();

	foo0.Add(dt, &ArgsBinding::foo, 1, 2);
	foo0();
	foo0.Remove(dt, &ArgsBinding::foo, 1, 2);
	foo0();

	foo0.Add(dt, &ArgsBinding::foo, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
	foo0();
	foo0.Remove(dt, &ArgsBinding::foo, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
	foo0();

	bar0.Add(dt, &ArgsBinding::bar, 1);
	bar0();
	bar0.Remove(dt, &ArgsBinding::bar, 1);
	bar0();

	bar0.Add(dt, &ArgsBinding::bar, 1, 2);
	bar0();
	bar0.Remove(dt, &ArgsBinding::bar, 1, 2);
	bar0();

	bar0.Add(dt, &ArgsBinding::bar, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
	bar0();
	bar0.Remove(dt, &ArgsBinding::bar, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
	bar0();
}
